#include "stdafx.h"
#include "MainCtrl.h"
#include "Attach.h"
#include "PakFile.h"
#include "Resource.h"
#include "SkinDlg.h"
#include "Psapi.h"
#pragma comment(lib, "psapi.lib")

CExeSendDict::CExeSendDict():CDictation(eSend)
{
}

CExeSendDict::~CExeSendDict()
{
    ReleaseCtrl();
}

bool CExeSendDict::Auther(CString & guid)
{
    if (!m_pOD) return false;
	m_pOD->id   = E_Author;
	m_pOD->size = 8;
	m_pOD->type = eSend;
	ReleaseCtrl();
	Sleep(100);
	DWORD rz = WaitCtrl();
	if (m_pOD->type == eRecv && m_pOD->size == 0)
	{
        CString str(m_pOD->pData);
        guid = str;
        return true;
	}
    return false;
}

bool CExeSendDict::SetSuccess()
{
    if (!m_pOD) return false;
    m_pOD->id = E_Success;
    m_pOD->size = 4;
    m_pOD->type = eSend;
    HANDLE hFile;
    if (!PAK().OpenFile(c_Pos, &hFile)) return false;
    DWORD dwSize = PAK().GetFileSize(hFile);
    PAK().ReadFile(hFile, m_pOD->pData, dwSize);
    PAK().CloseFile(hFile);
    m_pOD->size = dwSize;

    ReleaseCtrl();
    Sleep(100);
    DWORD rz = WaitCtrl();
    if (m_pOD->type == eRecv && m_pOD->size == 0)
    {
        //֪ͨHIDE
    }
    return false;
}

bool CExeSendDict::Heart(CString str)
{
    if (!m_pOD) return false;
    m_pOD->id   = E_Heart;
    m_pOD->size = str.GetLength()*2+2;
    lstrcpy( (LPTSTR)m_pOD->pData, str.GetString() );
    m_pOD->type = eSend;
    ReleaseCtrl();
    Sleep(100);
    DWORD rz = WaitCtrl();
    if (m_pOD->type == eRecv && m_pOD->size == 0)
    {
        return true;
    }
    return false;
}
bool CExeSendDict::GetPlayerPosition(sPos& pos)
{
    if (!m_pOD) return false;
	m_pOD->id = E_GetPlayerPos;
	m_pOD->size = 4;
	m_pOD->type = eSend;
	ReleaseCtrl();
	Sleep(100);
	DWORD rz = WaitCtrl();
	if (m_pOD->type == eRecv && m_pOD->size == 0)
	{
        sPos* pTmp = (sPos*)m_pOD->pData;
        pos = *pTmp;
        return true;
	}
    return false;
}

bool CExeSendDict::StartAttack(LPCTSTR configXml)
{
    if (!m_pOD) return false;
	m_pOD->id = E_StartAttack;
	m_pOD->size = sizeof(TCHAR)*(lstrlen(configXml)+1);
    lstrcpy( (LPTSTR)m_pOD->pData, configXml );
	m_pOD->type = eSend;
	ReleaseCtrl();
	Sleep(100);
	DWORD rz = WaitCtrl();
	if (m_pOD->type == eRecv && m_pOD->size != 0)
	{
        CString strName((WCHAR*)m_pOD->pData, m_pOD->size);
        AfxGetApp()->GetMainWnd()->SetWindowText(strName);
        //SetWindowText(NULL, strName);
        return true;
	}
    return false;
}

bool CExeSendDict::StopAttack()
{
    if (!m_pOD) return false;
	m_pOD->id = E_StopAttack;
	m_pOD->size = 4;
	m_pOD->type = eSend;
	ReleaseCtrl();
	Sleep(100);
	DWORD rz = WaitCtrl();
	if (m_pOD->type == eRecv && m_pOD->size == 0)
	{
        return true;
	}
    return false;
}

bool CExeSendDict::GoToCity()
{
    if (!m_pOD) return false;
	m_pOD->id = E_City;
	m_pOD->size = 4;
	m_pOD->type = eSend;
	ReleaseCtrl();
	Sleep(100);
	DWORD rz = WaitCtrl();
	if (m_pOD->type == eRecv && m_pOD->size == 0)
	{
        return true;
	}
    return false;
}

bool CExeSendDict::Quit()
{
    return 0;
}

CString CExeSendDict::GetUnitName()
{
    ;
    if (!m_pOD) return false;
	m_pOD->id = E_GetUnitName;
	m_pOD->size = 4;
	m_pOD->type = eSend;
	ReleaseCtrl();
	Sleep(100);
	DWORD rz = WaitCtrl();
	if (m_pOD->type == eRecv && m_pOD->size != 0)
	{
        CString strName((WCHAR*)m_pOD->pData, m_pOD->size);
        return strName;
	}
    return _T("");
}

CString CExeSendDict::GetPlayerName()
{
    return _T("");
}

CMainCtrl::CMainCtrl()
{
    m_h1 = new sData;
    m_h2 = NULL;
    m_h3 = new CExeSendDict;
    uThrProc uThr;
    uThr.ThrProc = (LPTHREAD_START_ROUTINE)CMainCtrl::RunThreadAuthor;
    uThr.PID = GetCurrentProcessId();
    uThr.pSend = this;
    PAK().WriteBuffFile((const char*)&uThr, sizeof(uThrProc), c_ThreadProc, 0);
    {
        HANDLE hFile = NULL;
        if (!PAK().OpenFile(c_ThreadProc, &hFile)) return ;
        DWORD dwSize = PAK().GetFileSize(hFile);
        uThrProc uThr;
        PAK().ReadFile(hFile, &uThr, min(dwSize, sizeof(uThrProc)));
        PAK().CloseFile(hFile);
    }
}

CMainCtrl::~CMainCtrl()
{
    if (m_h1) delete m_h1;
    if (m_h2) delete m_h2;
    if (m_h3) delete m_h3;
    m_pParent = NULL;
}

bool CMainCtrl::AttachDll(DWORD dwLoginMsg, CString strPath, HWND hExe, CString strDll, DWORD dwInstances)
{
    CAttach oAT;
    //if ( !IsRightVersion( oAT.GetProcess(hWow) ) ) return false;
    DWORD dd;
    m_h2 = new CExeSendDict;
    m_h2->Init(dd=GetTickCount());

    m_h1->pidWow = oAT.AttachDll(dwLoginMsg, strPath, hExe, strDll, dd, dwInstances);
    if (m_h1->pidWow) return true;
    return false;
}

bool CMainCtrl::AttachDll(DWORD dwLoginMsg, HWND hWow, HWND hExe, CString strDll, DWORD dwInstances)
{
    CAttach oAT;
    if ( !IsRightVersion( oAT.GetProcess(hWow) ) ) return false;
    DWORD dd;
    m_h2 = new CExeSendDict;
    m_h2->Init(dd=GetTickCount());

    m_h1->pidWow = oAT.AttachDll(dwLoginMsg, hWow, hExe, strDll, dd, dwInstances);
    if (m_h1->pidWow) return true;
    return false;
}

bool CMainCtrl::Auther(CString & guid)
{
    return m_h2->Auther(guid);
}

bool CMainCtrl::Start(LPCTSTR configXml)
{
    return m_h3->StartAttack(configXml);
}

bool CMainCtrl::Stop()
{
    return m_h3->StopAttack();
}

bool CMainCtrl::GoBackCity()
{
    return m_h3->GoToCity();
}

bool CMainCtrl::GetUnitPos(sPos& pos)
{
    return m_h3->GetPlayerPosition(pos);
}

CString CMainCtrl::GetPlayerName()
{
    CString str;
    return str;
}

CString CMainCtrl::GetUnitName()
{
    return m_h3->GetUnitName();
}

DWORD CMainCtrl::RunThreadAuthor(LPVOID pParam)
{
    DWORD dw = 0;
    __try
    {
        HANDLE hFile = NULL;
        if (!PAK().OpenFile(c_ThreadProc, &hFile)) return 0;
        DWORD dwSize = PAK().GetFileSize(hFile);
        uThrProc uThr;
        PAK().ReadFile(hFile, &uThr, min(dwSize, sizeof(uThrProc)));
        PAK().CloseFile(hFile);
        CMainCtrl* pTmp = (CMainCtrl*)uThr.pSend;
        //pTmp->m_h3->Init(dw=GetTickCount());
        dw = GetTickCount();
        pTmp->m_pParent->SendMessage(pTmp->m_pParent->m_WM_INIT_IPC, dw);
    }
    __except(1)
    {
        //throw __LINE__;
    }
    return dw;
}

bool CMainCtrl::IsRightVersion(HANDLE hProcess)
{
    if (NULL != hProcess )
    {
        HMODULE hMod;
        DWORD cbNeeded;
        WORD  chVer[256] = {0}; 
        TCHAR szProcessName[512];
        if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), 
            &cbNeeded) )
        {
            ::GetModuleFileNameEx( hProcess, hMod, szProcessName, 
                sizeof(szProcessName)/sizeof(TCHAR) );

            GetFileVersionInfo(szProcessName, 0, 256, chVer);
            CString strVersion;
            strVersion.Format(_T("%s%d"), _T("wowVersion\\"), chVer[26]);
            return !!PAK().HasFile(strVersion.GetString());
        }

    }
    return false;
}